import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Between } from 'typeorm';
import { Log } from '../../entities/log.entity';

@Injectable()
export class LogService {
  constructor(
    @InjectRepository(Log)
    private readonly logRepository: Repository<Log>,
  ) {}

  /**
   * 创建日志记录
   */
  async createLog(logData: Partial<Log>): Promise<Log> {
    const log = this.logRepository.create({
      ...logData,
      eventTime: logData.eventTime || new Date(),
      createdAt: new Date(),
      updatedAt: new Date(),
    });
    return await this.logRepository.save(log);
  }

  /**
   * 记录管理员操作
   */
  async logAdminOperation(
    uid: number,
    username: string,
    operationType: string,
    targetType: string,
    targetId?: number,
    targetName?: string,
    additionalInfo?: any,
    ipAddress?: string,
    userAgent?: string,
    status: number = 1,
  ): Promise<Log> {
    return await this.createLog({
      uid,
      username,
      type: 1, // 管理员操作
      operationType,
      targetType,
      targetId,
      targetName,
      logContent: additionalInfo,
      ipAddress,
      userAgent,
      status,
    });
  }

  /**
   * 记录登录日志
   */
  async logLogin(
    uid: number,
    username: string,
    loginResult: number,
    failureReason?: string,
    ipAddress?: string,
    userAgent?: string,
    deviceInfo?: string,
    location?: string,
  ): Promise<Log> {
    return await this.createLog({
      uid,
      username,
      type: 2, // 登录日志
      operationType: 'login',
      ipAddress,
      userAgent,
      deviceInfo,
      location,
      status: loginResult,
      failureReason,
      logContent: {
        loginTime: new Date(),
        sessionId: Math.random().toString(36).substring(7),
      },
    });
  }

  /**
   * 记录安全事件
   */
  async logSecurityEvent(
    eventType: string,
    description: string,
    securityLevel: number,
    ipAddress?: string,
    affectedUser?: string,
    affectedResource?: string,
    additionalInfo?: any,
  ): Promise<Log> {
    return await this.createLog({
      uid: 0, // 系统操作
      username: 'System',
      type: 3, // 安全事件
      operationType: eventType,
      logContent: {
        description,
        affectedUser,
        affectedResource,
        ...additionalInfo,
      },
      ipAddress,
      status: 2, // 默认失败状态，需要处理
      securityLevel,
      isRead: 0, // 标记为未读
    });
  }

  /**
   * 获取管理员操作日志（分页）
   */
  async getAdminOperations(
    page: number = 1,
    pageSize: number = 50,
    operationType?: string,
    adminId?: number,
    startDate?: Date,
    endDate?: Date,
    searchText?: string,
  ): Promise<{ data: Log[]; total: number; page: number; pageSize: number }> {
    const query = this.logRepository.createQueryBuilder('log')
      .where('log.type = :type', { type: 1 }); // 管理员操作

    if (operationType && operationType !== 'all') {
      query.andWhere('log.operationType = :operationType', { operationType });
    }

    if (adminId && adminId > 0) {
      query.andWhere('log.uid = :adminId', { adminId });
    }

    if (startDate && endDate) {
      query.andWhere('log.createdAt BETWEEN :startDate AND :endDate', {
        startDate,
        endDate,
      });
    }

    if (searchText) {
      query.andWhere(
        '(log.username LIKE :searchText OR log.targetName LIKE :searchText OR log.ipAddress LIKE :searchText)',
        { searchText: `%${searchText}%` }
      );
    }

    const total = await query.getCount();
    const data = await query
      .orderBy('log.createdAt', 'DESC')
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .getMany();

    return { data, total, page, pageSize };
  }

  /**
   * 获取登录日志（分页）
   */
  async getLoginLogs(
    page: number = 1,
    pageSize: number = 50,
    loginResult?: number,
    adminId?: number,
    startDate?: Date,
    endDate?: Date,
    searchText?: string,
  ): Promise<{ data: Log[]; total: number; page: number; pageSize: number }> {
    const query = this.logRepository.createQueryBuilder('log')
      .where('log.type = :type', { type: 2 }); // 登录日志

    if (loginResult && loginResult > 0) {
      query.andWhere('log.status = :status', { status: loginResult });
    }

    if (adminId && adminId > 0) {
      query.andWhere('log.uid = :adminId', { adminId });
    }

    if (startDate && endDate) {
      query.andWhere('log.createdAt BETWEEN :startDate AND :endDate', {
        startDate,
        endDate,
      });
    }

    if (searchText) {
      query.andWhere(
        '(log.username LIKE :searchText OR log.ipAddress LIKE :searchText OR log.location LIKE :searchText)',
        { searchText: `%${searchText}%` }
      );
    }

    const total = await query.getCount();
    const data = await query
      .orderBy('log.createdAt', 'DESC')
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .getMany();

    return { data, total, page, pageSize };
  }

  /**
   * 获取安全事件（分页）
   */
  async getSecurityEvents(
    page: number = 1,
    pageSize: number = 50,
    securityLevel?: number,
    isRead?: number,
    startDate?: Date,
    endDate?: Date,
    searchText?: string,
  ): Promise<{ data: Log[]; total: number; page: number; pageSize: number }> {
    const query = this.logRepository.createQueryBuilder('log')
      .where('log.type = :type', { type: 3 }); // 安全事件

    if (securityLevel !== undefined && securityLevel >= 0) {
      query.andWhere('log.securityLevel = :securityLevel', { securityLevel });
    }

    if (isRead !== undefined) {
      query.andWhere('log.isRead = :isRead', { isRead });
    }

    if (startDate && endDate) {
      query.andWhere('log.createdAt BETWEEN :startDate AND :endDate', {
        startDate,
        endDate,
      });
    }

    if (searchText) {
      query.andWhere(
        '(log.operationType LIKE :searchText OR log.ipAddress LIKE :searchText)',
        { searchText: `%${searchText}%` }
      );
    }

    const total = await query.getCount();
    const data = await query
      .orderBy('log.createdAt', 'DESC')
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .getMany();

    return { data, total, page, pageSize };
  }

  /**
   * 标记安全事件为已读
   */
  async markSecurityEventAsRead(logId: number): Promise<void> {
    await this.logRepository.update(logId, {
      isRead: 1,
      updatedAt: new Date(),
    });
  }

  /**
   * 解决安全事件
   */
  async resolveSecurityEvent(logId: number, resolution: string): Promise<void> {
    await this.logRepository.update(logId, {
      isResolved: 1,
      resolution,
      status: 1, // 标记为成功
      updatedAt: new Date(),
    });
  }

  /**
   * 获取统计信息
   */
  async getStatistics(): Promise<any> {
    const [
      totalAdminOperations,
      totalLogins,
      failedLogins,
      totalSecurityEvents,
      unreadSecurityEvents,
      criticalEvents,
    ] = await Promise.all([
      this.logRepository.count({ where: { type: 1 } }),
      this.logRepository.count({ where: { type: 2 } }),
      this.logRepository.count({ where: { type: 2, status: 2 } }),
      this.logRepository.count({ where: { type: 3 } }),
      this.logRepository.count({ where: { type: 3, isRead: 0 } }),
      this.logRepository.count({ where: { type: 3, securityLevel: 3 } }),
    ]);

    return {
      totalAdminOperations,
      totalLogins,
      failedLogins,
      totalSecurityEvents,
      unreadSecurityEvents,
      criticalEvents,
    };
  }

  /**
   * 清理过期日志（保留最近30天）
   */
  async cleanupOldLogs(): Promise<number> {
    const thirtyDaysAgo = new Date();
    thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

    const result = await this.logRepository
      .createQueryBuilder()
      .delete()
      .where('createdAt < :date', { date: thirtyDaysAgo })
      .execute();

    return result.affected || 0;
  }
}